package com.gitee.wsl.data.store

import com.gitee.wsl.io.api.removeAndGet
import com.gitee.wsl.reflect.TypeInfo
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlin.reflect.KClass

interface FlowStoreServer: StoreServer {
    val externalDataChangedFlow: MutableSharedFlow<Pair<String, Any?>>

    override fun remove(key: String) {
        removeAndGet<Any>(key)
    }
}

class FlowWarpStoreServer(val base: StoreServer): FlowStoreServer {

    override val externalDataChangedFlow: MutableSharedFlow<Pair<String, Any?>> = MutableSharedFlow(replay = 1)

    override fun <T : Any> getOrNull(name: String, type: KClass<T>): T? {
        return base.getOrNull(name, type)
    }

    override fun <T> getPreferenceOrNull(name: String, type: TypeInfo): T? {
        return base.getPreferenceOrNull(name, type)
    }

    override fun <T:Any> put(name: String, value: T) {
        base.put(name, value)
        notifyExternalDataChanged(name, value)
    }

    override fun remove(key: String) {
       val value = base.remove(key)
       notifyExternalDataChanged(key, null)
      return value
    }

    override fun isExits(key: String): Boolean {
        return base.isExits(key)
    }

    private fun notifyExternalDataChanged(key: String, value: Any?) {
         externalDataChangedFlow.tryEmit(key to value)
    }

}

fun <T> FlowStoreServer.getFlow(key: String) = externalDataChangedFlow.filter { it.first == key }.map { it.second as T? }